#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Gitee项目管理器 - 管理已有的Gitee仓库
"""

import requests
from typing import List, Dict, Tuple, Optional
from utils.logger import get_logger


class GiteeManager:
    """Gitee项目管理器"""
    
    def __init__(self, access_token: str, base_url: str = "https://gitee.com/api/v5"):
        self.access_token = access_token
        self.base_url = base_url
        self.session = requests.Session()
        self.logger = get_logger("GiteeManager")
        self.username = ""
        
                    # 设置请求头
        self.session.headers.update({
            'User-Agent': 'GiteeRepoManager/1.0'
        })
        
        # 获取用户名
        self._fetch_username()
    
    def _fetch_username(self):
        """获取当前用户名"""
        try:
            response = self.session.get(
                f"{self.base_url}/user",
                params={'access_token': self.access_token}
            )
            if response.status_code == 200:
                self.username = response.json().get('login', '')
                self.logger.info(f"获取用户名成功: {self.username}")
        except Exception as e:
            self.logger.error(f"获取用户名失败: {e}")
    
    def get_all_repositories(self, include_private: bool = True) -> Tuple[bool, List[Dict], str]:
        """
        获取用户的所有仓库
        
        Args:
            include_private: 是否包含私有仓库
            
        Returns:
            Tuple[bool, List[Dict], str]: (成功状态, 仓库列表, 消息)
        """
        try:
            repositories = []
            page = 1
            per_page = 100
            
            while True:
                params = {
                    'access_token': self.access_token,
                    'per_page': per_page,
                    'page': page,
                    'sort': 'updated',
                    'direction': 'desc'
                }
                
                response = self.session.get(f"{self.base_url}/user/repos", params=params)
                
                if response.status_code != 200:
                    error_msg = f"获取仓库列表失败，状态码: {response.status_code}"
                    self.logger.error(error_msg)
                    return False, [], error_msg
                
                repos = response.json()
                if not repos:
                    break
                
                # 过滤仓库
                for repo in repos:
                    if include_private or not repo.get('private', True):
                        repositories.append(repo)
                        # 调试：记录仓库信息
                        self.logger.info(f"仓库信息: name={repo.get('name')}, full_name={repo.get('full_name')}, path={repo.get('path')}")
                        self.logger.info(f"仓库所有者: {repo.get('owner', {}).get('login', 'Unknown')}")
                        # 记录所有字段供调试
                        repo_keys = list(repo.keys())
                        self.logger.info(f"仓库所有字段: {repo_keys}")
                
                page += 1
                
                # 防止无限循环
                if page > 50:  # 最多获取5000个仓库
                    break
            
            self.logger.info(f"成功获取 {len(repositories)} 个仓库")
            return True, repositories, f"成功获取 {len(repositories)} 个仓库"
            
        except Exception as e:
            error_msg = f"获取仓库列表异常: {str(e)}"
            self.logger.error(error_msg)
            return False, [], error_msg
    
    def delete_repository(self, repo_name: str) -> Tuple[bool, str]:
        """
        删除仓库
        
        Args:
            repo_name: 仓库名称
            
        Returns:
            Tuple[bool, str]: (成功状态, 消息)
        """
        try:
            if not self.username:
                return False, "无法获取用户名"
            
            url = f"{self.base_url}/repos/{self.username}/{repo_name}"
            response = self.session.delete(url, params={'access_token': self.access_token})
            
            if response.status_code == 204:
                self.logger.info(f"成功删除仓库: {repo_name}")
                return True, f"仓库 '{repo_name}' 删除成功"
            elif response.status_code == 404:
                return False, f"仓库 '{repo_name}' 不存在"
            elif response.status_code == 403:
                return False, f"没有权限删除仓库 '{repo_name}'"
            else:
                error_msg = f"删除仓库失败，状态码: {response.status_code}"
                self.logger.error(error_msg)
                return False, error_msg
                
        except Exception as e:
            error_msg = f"删除仓库异常: {str(e)}"
            self.logger.error(error_msg)
            return False, error_msg
    
    def update_repository_visibility(self, repo_name: str, is_private: bool) -> Tuple[bool, str]:
        """
        修改仓库可见性
        
        Args:
            repo_name: 仓库名称
            is_private: 是否私有
            
        Returns:
            Tuple[bool, str]: (成功状态, 消息)
        """
        try:
            if not self.username:
                return False, "无法获取用户名"
            
            # 从仓库名称中提取纯仓库名（去掉用户名前缀）
            repo_name_only = repo_name.split('/')[-1] if '/' in repo_name else repo_name
            
            # 查找对应的仓库信息以获取完整参数
            repo_info = next((repo for repo in getattr(self, '_cached_repos', [])
                              if repo.get('full_name') == repo_name or repo.get('path') == repo_name_only), 
                             None)
            
            # Gitee更新API使用 'private' (boolean) 参数，而不是 'public' (integer)
            data = {
                'name': repo_name_only,
                'description': repo_info.get('description', '') if repo_info else '',
                'homepage': repo_info.get('homepage', '') if repo_info else '',
                'private': is_private,
                'has_issues': repo_info.get('has_issues', True) if repo_info else True,
                'has_wiki': repo_info.get('has_wiki', True) if repo_info else True,
                'can_comment': repo_info.get('can_comment', True) if repo_info else True
            }
            
            # 构建正确的API路径
            if '/' in repo_name:
                # repo_name 已经包含用户名，直接使用
                url = f"{self.base_url}/repos/{repo_name}"
                repo_display_name = repo_name
            else:
                # 只有仓库名，添加当前用户名
                url = f"{self.base_url}/repos/{self.username}/{repo_name}"
                repo_display_name = f"{self.username}/{repo_name}"
            
            params = {'access_token': self.access_token}
            
            # 添加调试信息
            self.logger.info(f"修改仓库可见性: {repo_display_name}")
            self.logger.debug(f"请求URL: {url}")
            self.logger.debug(f"URL参数: {params}")
            self.logger.debug(f"表单数据: {data}")
            
            # 检查权限：只能修改自己的仓库
            if '/' in repo_name:
                owner_in_name = repo_name.split('/')[0]
                if owner_in_name != self.username:
                    self.logger.warning(f"无权修改他人仓库: {repo_name} (所有者: {owner_in_name}, 当前用户: {self.username})")
                    return False, f"无权修改仓库 '{repo_name}'，仓库属于用户 '{owner_in_name}'"
            
            response = self.session.patch(url, params=params, data=data)
            
            if response.status_code == 200:
                visibility_text = "私有" if is_private else "公开"
                self.logger.info(f"成功修改仓库可见性: {repo_name} -> {visibility_text}")
                return True, f"仓库 '{repo_name}' 已设置为{visibility_text}"
            elif response.status_code == 404:
                return False, f"仓库 '{repo_name}' 不存在"
            elif response.status_code == 403:
                return False, f"没有权限修改仓库 '{repo_name}'"
            else:
                error_msg = f"修改仓库可见性失败，状态码: {response.status_code}"
                self.logger.error(error_msg)
                return False, error_msg
                
        except Exception as e:
            error_msg = f"修改仓库可见性异常: {str(e)}"
            self.logger.error(error_msg)
            return False, error_msg
    
    def update_repository_description(self, repo_name: str, description: str) -> Tuple[bool, str]:
        """
        更新仓库描述
        
        Args:
            repo_name: 仓库名称
            description: 新的描述
            
        Returns:
            Tuple[bool, str]: (成功状态, 消息)
        """
        try:
            if not self.username:
                return False, "无法获取用户名"
            
            url = f"{self.base_url}/repos/{self.username}/{repo_name}"
            params = {
                'access_token': self.access_token
            }
            # 从仓库名称中提取纯仓库名（去掉用户名前缀）
            repo_name_only = repo_name.split('/')[-1] if '/' in repo_name else repo_name
            
            data = {
                'name': repo_name_only,  # API要求的name参数
                'description': description
            }
            
            # 构建正确的API路径
            if '/' in repo_name:
                # repo_name 已经包含用户名，直接使用
                url = f"{self.base_url}/repos/{repo_name}"
                repo_display_name = repo_name
            else:
                # 只有仓库名，添加当前用户名
                url = f"{self.base_url}/repos/{self.username}/{repo_name}"
                repo_display_name = f"{self.username}/{repo_name}"
            
            # 添加调试信息  
            self.logger.info(f"更新仓库描述: {repo_display_name}")
            self.logger.debug(f"请求URL: {url}")
            self.logger.debug(f"URL参数: {params}")
            self.logger.debug(f"表单数据: {data}")
            
            # 检查权限：只能修改自己的仓库
            if '/' in repo_name:
                owner_in_name = repo_name.split('/')[0]
                if owner_in_name != self.username:
                    self.logger.warning(f"无权修改他人仓库: {repo_name} (所有者: {owner_in_name}, 当前用户: {self.username})")
                    return False, f"无权修改仓库 '{repo_name}'，仓库属于用户 '{owner_in_name}'"
            
            # 使用正确的参数传递方式
            response = self.session.patch(url, params=params, data=data)
            
            # 记录响应详情
            self.logger.debug(f"响应状态码: {response.status_code}")
            self.logger.debug(f"响应头: {response.headers}")
            try:
                response_text = response.text
                self.logger.debug(f"响应内容: {response_text}")
            except:
                pass
            
            if response.status_code == 200:
                self.logger.info(f"成功更新仓库描述: {repo_name}")
                return True, f"仓库 '{repo_name}' 描述已更新"
            elif response.status_code == 404:
                error_msg = f"仓库 '{repo_name}' 不存在。完整路径: {self.username}/{repo_name}"
                self.logger.error(f"404错误: {error_msg}")
                try:
                    error_detail = response.json()
                    self.logger.error(f"错误详情: {error_detail}")
                except:
                    pass
                return False, error_msg
            elif response.status_code == 403:
                error_msg = f"没有权限修改仓库 '{repo_name}'"
                self.logger.error(f"403错误: {error_msg}")
                return False, error_msg
            else:
                error_msg = f"更新仓库描述失败，状态码: {response.status_code}"
                self.logger.error(error_msg)
                try:
                    error_detail = response.json()
                    self.logger.error(f"错误详情: {error_detail}")
                    # 如果有具体的错误消息，使用它
                    if 'message' in error_detail:
                        error_msg = f"API错误: {error_detail['message']}"
                    elif 'error' in error_detail:
                        error_msg = f"API错误: {error_detail['error']}"
                except Exception as e:
                    try:
                        response_text = response.text
                        self.logger.error(f"原始响应: {response_text}")
                        error_msg += f" 响应: {response_text}"
                    except:
                        pass
                return False, error_msg
                
        except Exception as e:
            error_msg = f"更新仓库描述异常: {str(e)}"
            self.logger.error(error_msg)
            return False, error_msg
    
    def batch_delete_repositories(self, repo_names: List[str]) -> Dict[str, Tuple[bool, str]]:
        """
        批量删除仓库
        
        Args:
            repo_names: 仓库名称列表
            
        Returns:
            Dict[str, Tuple[bool, str]]: {仓库名: (成功状态, 消息)}
        """
        results = {}
        
        for repo_name in repo_names:
            success, message = self.delete_repository(repo_name)
            results[repo_name] = (success, message)
            
        return results
    
    def batch_update_visibility(self, repo_names: List[str], is_private: bool) -> Dict[str, Tuple[bool, str]]:
        """
        批量修改仓库可见性
        
        Args:
            repo_names: 仓库名称列表
            is_private: 是否私有
            
        Returns:
            Dict[str, Tuple[bool, str]]: {仓库名: (成功状态, 消息)}
        """
        results = {}
        
        for repo_name in repo_names:
            success, message = self.update_repository_visibility(repo_name, is_private)
            results[repo_name] = (success, message)
            
        return results
    
    def batch_update_descriptions(self, repo_descriptions: Dict[str, str]) -> Dict[str, Tuple[bool, str]]:
        """
        批量更新仓库描述
        
        Args:
            repo_descriptions: {仓库名: 描述} 字典
            
        Returns:
            Dict[str, Tuple[bool, str]]: {仓库名: (成功状态, 消息)}
        """
        results = {}
        
        for repo_name, description in repo_descriptions.items():
            success, message = self.update_repository_description(repo_name, description)
            results[repo_name] = (success, message)
            
        return results
